package com.lwc.geojson.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lwc.geojson.entity.SystemGeo;
import com.lwc.geojson.mapper.SystemGeoMapper;
import com.lwc.geojson.service.SystemGeoService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.n52.jackson.datatype.jts.JtsModule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;


/**
 * SystemGeo 服务实现类
 *
 * @author luwc
 * @time 2025-04-19 22:10:43
 */
@Service
@Slf4j
public class SystemGeoServiceImpl extends ServiceImpl<SystemGeoMapper, SystemGeo>
        implements SystemGeoService {

    @Autowired
    private GeometryFactory geometryFactory;
    @Autowired
    private SystemGeoMapper systemGeoMapper;

    @Override
    public void importGeoJsonData(String filePath) throws IOException {
        InputStream inputStream = new ClassPathResource(filePath).getInputStream();

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JtsModule(geometryFactory));
        // 方式1：直接使用正确类型
        GeoJson geoJson = objectMapper.readValue(inputStream, GeoJson.class);

        // 清空现有数据
//        this.baseMapper.delete(new QueryWrapper<>());

        for (GeoJson.Feature feature : geoJson.getFeatures()) {
            Geometry geometry = feature.getGeometry();
//            log.debug("Geometry WKT: {}", geometry.toText());
//            if (!geometry.isValid()) {
//                log.warn("Invalid geometry found: {}", geometry.toText());
//                continue;
//            } else {
//                log.warn("数据正常");
//            }
            GeoJson.Properties properties = feature.getProperties();
            SystemGeo systemGeo1 = baseMapper.selectOne(new LambdaQueryWrapper<SystemGeo>().eq(SystemGeo::getAdcode, properties.getAdcode()));
            if (systemGeo1 != null) {
                log.info("已存在,{}", feature.getProperties().getName());
                continue;
            }

            log.info("新加,{}", feature.getProperties().getName());

            SystemGeo systemGeo = new SystemGeo();
            systemGeo.setAdcode(properties.getAdcode());
            if (properties.getName().equals("")) {
                systemGeo.setName("十段线");
            } else {
                systemGeo.setName(properties.getName());
            }
            if (properties.getCenter() != null) {
                List<Double> center = properties.getCenter();
                systemGeo.setCenterLon(center.get(0));
                systemGeo.setCenterLat(center.get(1));
            } else {
                systemGeo.setCenterLon(0d);
                systemGeo.setCenterLat(0d);
            }

//            systemGeo.setBoundary(geometry);
            systemGeo.setBoundaryWkt(geometry.toText());

            Envelope envelope = geometry.getEnvelopeInternal();
            systemGeo.setBboxMinLon(envelope.getMinX());
            systemGeo.setBboxMaxLon(envelope.getMaxX());
            systemGeo.setBboxMinLat(envelope.getMinY());
            systemGeo.setBboxMaxLat(envelope.getMaxY());

            this.baseMapper.insertWithWkt(systemGeo);
        }
    }

    @Data
    public static class GeoJson {
        @JsonProperty("type")
        private String type;
        @JsonProperty("features")
        private List<Feature> features;

        // 必须有无参构造函数
        public GeoJson() {
        }

        @Data
        public static class Feature {
            @JsonProperty("type")
            private String type;
            @JsonProperty("properties")
            private Properties properties;
            @JsonProperty("geometry")
            private Geometry geometry;

            public Feature() {
            }
        }

        @Data
        public static class Properties {
            private String adcode;
            private String name;
            private List<Double> center;
            private List<Double> centroid;
            private Integer childrenNum;
            private String level;
            private Map<String, Object> parent;
            private Integer subFeatureIndex;
            private List<Double> acroutes;
            private String adchar;

            public Properties() {
            }
        }
    }
}
